﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SmartSpace.OrganizationalStructure
{
    public partial class OrganizationService : IOrganizationService
    {
        public bool SaveOrganization(Organization organization)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                if (context.Set<Organization>().Where(p => p.Id == organization.Id).Select(p => p.Id)
                    .SingleOrDefault() == default(Guid))
                {
                    context.Set<Organization>().Add(organization);
                }
                else
                {
                    context.Entry(organization).State = System.Data.Entity.EntityState.Modified;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }

                return false;
            }
        }

        public bool DeleteOrganization(Organization organization)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                if (context.Set<Organization>().Where(p => p.Id == organization.Id).Select(p => p.Id)
                    .SingleOrDefault() == default(Guid))
                {
                    return true;
                }
                else
                {
                    context.Entry(organization).State = System.Data.Entity.EntityState.Deleted;
                }

                if (context.SaveChanges() > 0)
                {
                    return true;
                }

                return false;
            }
        }

        public Organization GetOrganization(Guid id, bool isRecursive)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                Organization model = context.Set<Organization>().Where(p => p.Id == id).SingleOrDefault();

                if (isRecursive && model != null)
                {
                    Stack<Organization> stack = new Stack<Organization>();
                    stack.Push(model);

                    while (stack.Count > 0)
                    {
                        Organization parentItem = stack.Pop();
                        parentItem.Children = context.Set<Organization>().Where(p => p.ParentId.Value == parentItem.Id).ToList();
                        foreach (var item in parentItem.Children)
                        {
                            stack.Push(item);
                        }
                    }
                }

                return model;
            }
        }

        public Organization GetOrganization(string code, bool isRecursive)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                Organization model = context.Set<Organization>().Where(p => p.Code == code).SingleOrDefault();

                if (isRecursive && model != null)
                {
                    Stack<Organization> stack = new Stack<Organization>();
                    stack.Push(model);

                    while (stack.Count > 0)
                    {
                        Organization parentItem = stack.Pop();
                        parentItem.Children = context.Set<Organization>().Where(p => p.ParentId.Value == parentItem.Id).ToList();
                        foreach (var item in parentItem.Children)
                        {
                            stack.Push(item);
                        }
                    }
                }

                return model;
            }
        }

        public List<Organization> GetChildren(Guid id, bool isRecursive)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                List<Organization> models = context.Set<Organization>().Where(p => p.ParentId.Value == id).ToList();

                if (isRecursive && models != null)
                {
                    Stack<Organization> stack = new Stack<Organization>();
                    for (int i = 0; i < models.Count; i++)
                    {
                        stack.Push(models[i]);
                    }

                    while (stack.Count > 0)
                    {
                        Organization parentItem = stack.Pop();
                        parentItem.Children = context.Set<Organization>().Where(p => p.ParentId.Value == parentItem.Id).ToList();
                        foreach (var item in parentItem.Children)
                        {
                            stack.Push(item);
                        }
                    }
                }

                return models;
            }
        }

        public List<Organization> GetChildren(string code, bool isRecursive)
        {
            using (OrganizationalStructureDbContext context = new OrganizationalStructureDbContext())
            {
                List<Organization> models = context.Set<Organization>().Where(p => p.Parent.Code == code).ToList();

                if (isRecursive && models != null)
                {
                    Stack<Organization> stack = new Stack<Organization>();
                    for (int i = 0; i < models.Count; i++)
                    {
                        stack.Push(models[i]);
                    }

                    while (stack.Count > 0)
                    {
                        Organization parentItem = stack.Pop();
                        parentItem.Children = context.Set<Organization>().Where(p => p.ParentId.Value == parentItem.Id).ToList();
                        foreach (var item in parentItem.Children)
                        {
                            stack.Push(item);
                        }
                    }
                }

                return models;
            }
        }
    }
}
